package com.yike.user.utils;

import com.yike.common.exception.BusinessException;
import com.yike.user.entity.PlatformMenu;
import com.yike.user.vo.PlatformMenuTreeVo;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Sakura
 * @date 2024/10/30 14:10
 */
@Log
public class PlatformMenuUtil {

    public static List<PlatformMenuTreeVo> getPlatformMenuTreeVos(List<PlatformMenu> platformMenus) {
        int num = 0;
        return getChildMenus(0L, platformMenus, num, new HashSet<>());
    }

    private static List<PlatformMenuTreeVo> getChildMenus(Long parentId, List<PlatformMenu> platformMenus, int num, Set<Long> visited) {
        num++;
        if (num > 10) {
            log.info("菜单数据异常，parentId：" + parentId);
            throw new BusinessException(500, "菜单数据异常，请联系管理人员");
        }

        // 检测循环引用
        if (!visited.add(parentId)) {
            log.info("检测到循环引用，parentId：" + parentId);
            throw new BusinessException(500, "菜单数据异常，存在循环引用");
        }

        List<PlatformMenuTreeVo> resultList = new ArrayList<>();

        for (PlatformMenu platformMenu : platformMenus) {
            if (parentId.equals(platformMenu.getParentId())) {
                PlatformMenuTreeVo platformMenuTreeVo = new PlatformMenuTreeVo();
                BeanUtils.copyProperties(platformMenu, platformMenuTreeVo);

                List<PlatformMenuTreeVo> childMenuTreeVos = getChildMenus(platformMenu.getId(), platformMenus, num, visited);
                platformMenuTreeVo.setChildren(childMenuTreeVos);

                resultList.add(platformMenuTreeVo);
            }
        }

        visited.remove(parentId); // 递归完成后移除该节点，允许在其他路径中使用
        return resultList;
    }

    public static List<com.yike.common.vo.PlatformMenuTreeVo> getLoginMenus(List<PlatformMenu> platformMenus) {
        return getLoginChildMenus(0L, platformMenus, 0, new HashSet<>());
    }

    private static List<com.yike.common.vo.PlatformMenuTreeVo> getLoginChildMenus(Long parentId, List<PlatformMenu> platformMenus, int num, Set<Long> visited) {
        num++;
        if (num > 10) {
            log.info("菜单数据异常，parentId：" + parentId);
            throw new BusinessException(500, "菜单数据异常，请联系管理人员");
        }

        // 检测循环引用
        if (!visited.add(parentId)) {
            log.info("检测到循环引用，parentId：" + parentId);
            throw new BusinessException(500, "菜单数据异常，存在循环引用");
        }

        List<com.yike.common.vo.PlatformMenuTreeVo> resultList = new ArrayList<>();

        for (PlatformMenu platformMenu : platformMenus) {
            if (parentId.equals(platformMenu.getParentId())) {
                com.yike.common.vo.PlatformMenuTreeVo platformMenuTreeVo = new com.yike.common.vo.PlatformMenuTreeVo();
                BeanUtils.copyProperties(platformMenu, platformMenuTreeVo);

                // 递归调用获取子菜单
                List<com.yike.common.vo.PlatformMenuTreeVo> childMenuTreeVos = getLoginChildMenus(platformMenu.getId(), platformMenus, num, visited);
                platformMenuTreeVo.setChildren(childMenuTreeVos);

                resultList.add(platformMenuTreeVo);
            }
        }

        visited.remove(parentId); // 递归完成后移除该节点，允许在其他路径中使用
        return resultList;
    }
}
